package driver;

import fitness.FitnessCalc;
import gene.ChinkleException;
import gene.Gene;
import gene.Input;

import java.util.ArrayList;

import chromo.Chromosome;
import chromo.Population;

public class Driver {
	
	public static void main(String[] args) throws ChinkleException{
		run(4000);
	}
	public static void run(int numTimes){
		
		//Defining initial inputs
		ArrayList<Input> inputs = new ArrayList<Input>();
		Chromosome.defaultInputs = 4;
		inputs.add(new Input(0, false));
		inputs.add(new Input(1, true));
		inputs.add(new Input(2));
		inputs.add(new Input(3));
		inputs.add(new Input(4));
		inputs.add(new Input(5));
		
		//Inputs the desired output
		ArrayList<Boolean> output = new ArrayList<Boolean>();
		output.add(false);		
		output.add(false);
		output.add(false);
		output.add(false);
		
		output.add(false);
		output.add(true);
		output.add(true);
		output.add(false);
		
		output.add(false);
		output.add(true);
		output.add(true);
		output.add(false);
		
		output.add(false);
		output.add(false);
		output.add(false);
		output.add(false);
		
		FitnessCalc.setSolution(output);
//		ArrayList<Boolean> output2 = new ArrayList<Boolean>();
//		output2.add(false);		
//		output2.add(false);
//		output2.add(true);
//		output2.add(true);
//		
//		output2.add(true);
//		output2.add(true);
//		output2.add(false);
//		output2.add(false);
//		
//		output2.add(true);
//		output2.add(true);
//		output2.add(false);
//		output2.add(false);
//		
//		output2.add(false);
//		output2.add(false);
//		output2.add(true);
//		output2.add(true);
//		FitnessCalc.setSolution(output2);
		
		Population testPop = null;
		//Set population size below
		int popSize = 100000;
		Chromosome temp = null;
		try{
			testPop = new Population(inputs, popSize);
			int generationCount = 0;
			int oldFitness = 0;
			int counter = 0;
			while (generationCount < numTimes){
				generationCount++;
				if(generationCount % 25 == 0 && testPop.getFittest().getFitness() != FitnessCalc.maxFitness()){
					System.out.println(generationCount);
				}
				testPop = Algorithm.evolvePopulation(testPop);
				temp = testPop.getFittest();
				if(oldFitness < temp.getFitness()){
					System.out.println("New Fitness! = " + temp.getFitness());
					oldFitness = temp.getFitness();
					System.out.println(temp);
					System.out.println(temp.getAllOutputs());
				}
				
				if(testPop.getFittest().getFitness() == FitnessCalc.maxFitness() && oldFitness != 0){
					counter++;
					//Adjust the 100 below to change how long the program will look for a new fitness
					if(counter == 100){
						break;
					}
				}
				
				if(generationCount % 200 == 0 && testPop.getFittest().getFitness() != FitnessCalc.maxFitness()){
					Chromosome.size = Chromosome.size+1;
					System.out.println("Chromosome size is now " + Chromosome.size);
					testPop = new Population(inputs, popSize);
				}
			}
		}
		catch(ChinkleException e){
			System.err.println(e.getMessage());
		}
		System.out.println(temp);
		System.out.println(testPop.getFittest());
		System.out.println(testPop.getFittest().getAllOutputs());
	}
}
